package com.feidee.data.report.util;

import com.feidee.data.report.constant.Constant;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;

/*******************************************
 * 最简单的AES加密方式，不需要随机向量iv，也不需要cbc 和padding
 * @author  xiong.xing
 * @version 0.1
 * @date     2010-6-23
 *******************************************/
public class SimpleAES {
	private static final String Algorithm = "AES";
	
	
	public static void main(String[] args) throws Exception {
	    System.out.println(encrypt("{"

	            + "\"mysql.warehouse.url\":\"jdbc:mysql://192.168.241.171:3306/data_report?useUnicode=true&amp;characterEncoding=utf8&amp;rewriteBatchedStatements=true\","

	            + "\"mysql.warehouse.user\":\"PT_reportsystem\","

	            + "\"mysql.warehouse.pwd\":\"6cc783d6f8cHcfc_5d67de5556db\","

	            + "\"mysql.java.driver.class\":\"com.mysql.jdbc.Driver\"}", Constant.MYSQL_DECRYPT_KEY));

        System.out.println(decrypt("cd2a88683a7a90467bfe110becc91693c65b625f3354b6186ab55f5b38f53f74055e9aa39f63c8a5dd7fba4060448ba2c15bc541f2f58a1ce97baf7071bd099963c4b5498c89aac6941b68f0b50025596e21b17a3b82f511b67a0d5667872fa5c0fd297e052d1614b3c70bfa5ac535fc6164f420ef890719dd77d967e74e671fbf5967324070a3618750fac093b69d7516eedab2a5f2ecf8280737b64bbc24da43413ce11b1e7069865d5c2e04eea53a316503496f08d5f20493add999a6c9b837e13755bd3531c06ca55f37679989228b2cb94c61a30cbc899ed51ddfae2fc94ff0ffedc966634f1d2bd332047aa25e791e14404c6b428ed4b7baba279ab80cca635d3a1020e8917ec7d7e66890a2d4cdee9344bdc73c68b4025f8b52bf205d", Constant.MYSQL_DECRYPT_KEY));

		System.out.println(decrypt("cd2a88683a7a90467bfe110becc916934eda948c22166d307bbf3c6aae61b253586da4b6d0ed7f9c1eb92ab910e06f01c6949557f4591afc5331c86d4d4cba6963c4b5498c89aac6941b68f0b50025591ec762e96a541a4e6c06ecc74ccc9fd12d454f429f999ecfa7876d46697c5d31b48ee87cc4364f16aa97936f555066b334e64fe7af73db639dd752e22f3a4d38162c473b7db793d0228357e3d8515487eb1a1d33e08ace6b4fd4f7132fb7b1628c304a43db2c8e718ddde9769f69a2ca1db91fe2a0abb5d72299e0b2b9c9b2a685e06c7ce6fe40aafd89fe3cad534e1627982ae600f75c3a82b7142d3f3733e878b9ed323da8750140aece81bc015827f288dd5c04b2fd0af97b2c6f39612795583586bb32b565dc527f007fc33cb9e1f1122a0570480ff89a0ed6c16580e282792f3a478aaec2d08f4767b16150daf852b7e0591c407d12bda860b1a5e457f3dc64f42b78e3b3e8a129fdc633dd72bc4317593567b2bbea295427064a611be059e937b57deef6c8712df524dd48424a", Constant.MYSQL_DECRYPT_KEY));

    }
	/**
     * 加密
     * @param plainText 明文
     * @param iv 16位的随机码 
     * @return
	 * @throws Exception 
     */
    public static String encrypt(String plainText,String password) throws Exception {
    	try{
    		return toHex(encrypt(plainText.getBytes("UTF-8"),password));
    	}catch (UnsupportedEncodingException e) {
    		throw new UnsupportedEncodingException("SimpleAES encrypt UnsupportedEncodingException:"+e.getMessage());
		} catch (Exception e) {
		    throw new Exception("SimpleAES encrypt Exception:"+e.getMessage());
        }
    }

    
    /**
     * 解密 以String密文输入,String明文输出
     * @param strMi
     * @return
     * @throws Exception 
     */
    public static String decrypt(String cipherText,String password) throws Exception {
    	try{
	    	byte[] bytes = decrypt(hexTobytes(cipherText),password);
	        return new String(bytes,"UTF-8");
	    }catch (UnsupportedEncodingException e) {
			throw new  Exception("SimpleAES decrypt exceptioon:"+e.getMessage());
		} 
    }

    /**
     * 加密以byte[]明文输入,byte[]密文输出
     * @param byteS
     * @return
     * @throws Exception 
     */
    public static byte[] encrypt(byte[] byteS,String pwd) throws Exception {
    	
        byte[] byteFina = null;
        Cipher cipher;
        try {
            cipher = Cipher.getInstance(Algorithm);

			SecretKeySpec keySpec = new SecretKeySpec(getKey(pwd), "AES");

			cipher.init(Cipher.ENCRYPT_MODE, keySpec);
			byteFina = cipher.doFinal(byteS);
        } catch (Exception e) {
        	throw new  Exception("SimpleAES Encrypt exceptioon:"+e.getMessage());
        } finally {
            cipher = null;
        }
        
        return byteFina;
    }

    /**
     * 解密以byte[]密文输入,以byte[]明文输出
     * @param byteD
     * @return
     * @throws Exception 
     */
    public static byte[] decrypt(byte[] byteD,String pwd) throws Exception {
        Cipher cipher;
        byte[] byteFina = null;
        try {
            cipher = Cipher.getInstance(Algorithm);

    		SecretKeySpec keySpec = new SecretKeySpec(getKey(pwd), "AES");

    		cipher.init(Cipher.DECRYPT_MODE, keySpec);

    		byteFina = cipher.doFinal(byteD);
    		
        } catch (Exception e) {
            throw new  Exception(e);
        } finally {
            cipher = null;
        }
        return byteFina;
    }
    
    private static byte[] getKey(String password) throws UnsupportedEncodingException{
    	if(password.length() > 16)
    		password = password.substring(0, 16);
    	else if(password.length() < 16){
    		int count = (16 - password.length()); 
    		for(int i=0;i<count;i++){
    			password+="0";
    		}
    	}
    	
    	return password.getBytes("UTF-8");
    }
    

    /**
     * Convert byte array to hex string
     */
    public static String toHex(byte[] bytes){
        StringBuffer sb = new StringBuffer(bytes.length * 3);
        for (int i = 0; i < bytes.length; i++) {
            int val = ((int) bytes[i]) & 0xff;
            if (val < 16)
                sb.append("0");
            
            sb.append(Integer.toHexString(val));
            
        }
        
        return sb.toString();
    }
    
    /**
     * Convert hex string to byte array 
     * @param str
     * @return
     */
    public static byte[] hexTobytes(String str){
        int l = str.length();
        if ((l % 2) != 0) {
            throw new IllegalArgumentException("长度不是偶数!");
        }
        byte[] bytes = new byte[l/2];
        for(int i=0;i<l;i=i+2){
            String item = str.substring(i, i+2);
            bytes[i/2] = (byte)Integer.parseInt(item, 16);
        }
        
        return bytes;
    }
 
}
